import os
import re
import time
import allure
import pytest
from playwright.sync_api import Page, expect
from utils.log import LoggerUtils
from utils.send_error_feishu import send_message


class BasePage(object):

    def __init__(self, page: Page):
        self.page = page
        self.log = LoggerUtils().logger()
        self.retry = 4

    def goto(self, url: str):
        """
        打开被测网站
        :param url:
        :return:
        """
        try:
            with allure.step(f"跳转到:{url}"):
                self.log.info(f'访问的URL---{url}')
                return self.page.goto(url)
        except Exception as e:
            self.screenshot()
            self.browser_浏览器操作(reload=True)
            error_info = f'访问URL:{url}失败，错误信息：{e}'
            send_message(error_info)
            self.log.error(error_info)

    def locator(self, selector, num=0, retry=5, iframe=None, iframe_to=None,hover=True):
        """
        根据locator的定位方式：支持xpath,css,id的方式进行定位,id=> #id
        :param hover:
        :param iframe_to:在iframe层级里面在嵌套iframe
        :param num:表示第几个元素，默认从第一个元素开始获取
        :param selector: 元素的定位信息
        :param retry: 重试次数
        :param iframe: iframe层级
        :return:
        """
        for itme in range(retry + 1):
            start_time1 = time.time()
            try:

                if iframe is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).locator(selector).nth(num)
                    loc.wait_for(state="visible", timeout=10000)
                    if hover:
                        loc.hover()
                    loc.is_enabled()
                    loc.is_visible()
                    loc.focus()
                    loc.scroll_into_view_if_needed()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                elif iframe_to is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).frame_locator(iframe_to).locator(selector).nth(num)
                    loc.wait_for(state="visible", timeout=10000)
                    if hover:
                        loc.hover()
                    loc.is_enabled()
                    loc.is_visible()
                    loc.focus()
                    loc.scroll_into_view_if_needed()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                else:
                    start_time = time.time()
                    loc = self.page.locator(selector).nth(num)
                    loc.wait_for(state="visible", timeout=10000)
                    if hover:
                        loc.hover()
                    loc.is_enabled()
                    loc.is_visible()
                    loc.focus()
                    loc.scroll_into_view_if_needed()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,耗时：{end_time - start_time:.3f}秒')
                    self.screenshot()
                    return loc

            except Exception as e:
                error_info = f"元素：{selector}定位失败，错误信息：{e}"

                self.log.error(error_info)
                if itme < retry:
                    end_time1 = time.time()
                    wait_time = (itme + 1) * 1000
                    self.log.info(
                        f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}，耗时：{end_time1 - start_time1:.3f}秒")
                    self.wait_for_timeout(wait_time)
                    send_message(f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}")
                    # 元素找不到刷新页面
                    # self.browser_浏览器操作(reload=True)
                else:
                    # 关闭浏览器
                    self.page.close()
                    # 将错误信息通过飞书通知
                    send_message(error_info)
                    # 报错截图
                    self.screenshot()
                    raise Exception(error_info)

    def get_by_text(self, selector, exact=False, retry=5, iframe=None, iframe_to=None,nth=0,hover=True):
        """
        使用get_by_text定位方式
        :param exact:
        :param selector: 元素位置
        :param retry: 重试次数
        :param iframe: iframe
        :param iframe_to: 嵌套iframe
        :return:
        """
        for itme in range(retry + 1):
            start_time1 = time.time()
            try:
                if iframe is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).get_by_text(selector, exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    if hover:
                        loc.hover()
                    loc.scroll_into_view_if_needed()
                    loc.is_enabled()
                    loc.is_visible()
                    loc.focus()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                elif iframe_to is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).frame_locator(iframe_to).get_by_text(selector,
                                                                                               exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    if hover:
                        loc.hover()
                    loc.scroll_into_view_if_needed()
                    loc.is_enabled()
                    loc.is_visible()
                    loc.focus()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                else:
                    start_time = time.time()
                    loc = self.page.get_by_text(selector, exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    if hover:
                        loc.hover()
                    loc.scroll_into_view_if_needed()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()

                    self.log.info(f'元素：{selector}定位成功,耗时：{end_time - start_time:.3f}秒')
                    # self.page.wait_for_timeout(100)
                    self.screenshot()
                    return loc
            except Exception as e:
                error_info = f"元素：{selector}定位失败，错误信息：{e}"
                self.log.error(error_info)
                if itme < retry:

                    end_time1 = time.time()
                    wait_time = (itme + 1) * 1000
                    self.log.info(
                        f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}，耗时：{end_time1 - start_time1:.3f}秒")
                    self.wait_for_timeout(wait_time)
                    send_message(f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}")

                    # self.browser_浏览器操作(reload=True)
                else:
                    self.page.close()
                    send_message(error_info)
                    self.screenshot()
                    raise Exception(error_info)


    def get_by_role(self, role_name, exact=False, retry=5, iframe=None, iframe_to=None,nth=0,hover=True):
        """
        使用get_by_role定位方式
        :param exact:
        :param role_name:
        :param retry: 重试次数
        :param iframe: iframe
        :param iframe_to: 嵌套iframe
        :return:
        """
        for itme in range(retry + 1):
            start_time1 = time.time()
            try:
                if iframe is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).get_by_role(role=role_name[0], name=role_name[1],
                                                                      exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()

                    self.log.info(f'元素：{role_name}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                elif iframe_to is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).frame_locator(iframe_to).get_by_role(role=role_name[0],
                                                                                               name=role_name[1],
                                                                                               exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()

                    self.log.info(f'元素：{role_name}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                else:
                    start_time = time.time()
                    loc = self.page.get_by_role(role=role_name[0], name=role_name[1], exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{role_name}定位成功,耗时：{end_time - start_time:.3f}秒')
                    # self.page.wait_for_timeout(100)
                    self.screenshot()
                    return loc
            except Exception as e:
                error_info = f"元素：{role_name}定位失败，错误信息：{e}"
                self.log.error(error_info)
                if itme < retry:
                    end_time1 = time.time()
                    wait_time = (itme + 1) * 1000
                    self.log.info(
                        f"元素：{role_name}正在重新定位，当前重试次数：{itme + 1}/{retry}，耗时：{end_time1 - start_time1:.3f}秒")
                    self.wait_for_timeout(wait_time)
                    send_message(f"元素：{role_name}正在重新定位，当前重试次数：{itme + 1}/{retry}")

                    # self.browser_浏览器操作(reload=True)
                else:
                    self.page.close()
                    send_message(error_info)
                    self.screenshot()
                    raise Exception(error_info)

    def get_by_label(self, selector, exact=False, retry=5, iframe=None, iframe_to=None,nth=0,hover=True):
        """
        使用get_by_label定位方式
        :param exact:
        :param selector: 元素位置
        :param retry: 重试次数
        :param iframe: iframe
        :param iframe_to: 嵌套iframe
        :return:
        """
        for itme in range(retry + 1):
            start_time1 = time.time()
            try:
                if iframe is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).get_by_label(selector, exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')

                    return loc
                elif iframe_to is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).frame_locator(iframe_to).get_by_label(selector, exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                else:
                    start_time = time.time()
                    loc = self.page.get_by_label(selector, exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,耗时：{end_time - start_time:.3f}秒')

                    self.screenshot()
                    return loc
            except Exception as e:
                error_info = f"元素：{selector}定位失败，错误信息：{e}"
                self.log.error(error_info)
                if itme < retry:
                    end_time1 = time.time()
                    wait_time = (itme + 1) * 1000
                    self.log.info(
                        f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}，耗时：{end_time1 - start_time1:.3f}秒")
                    self.wait_for_timeout(wait_time)
                    send_message(f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}")

                    # self.browser_浏览器操作(reload=True)
                else:
                    self.page.close()
                    send_message(error_info)
                    self.screenshot()
                    raise Exception(error_info)

    def get_by_title(self, selector, exact=False, retry=5, iframe=None, iframe_to=None,nth=0,hover=True):
        """
        使用get_by_text定位方式
        :param exact:
        :param selector: 元素位置
        :param retry: 重试次数
        :param iframe: iframe
        :param iframe_to: 嵌套iframe
        :return:
        """
        for itme in range(retry + 1):
            start_time1 = time.time()
            try:
                if iframe is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).get_by_title(selector, exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                elif iframe_to is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).frame_locator(iframe_to).get_by_title(selector,
                                                                                                exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                else:
                    start_time = time.time()
                    loc = self.page.get_by_title(selector, exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,耗时：{end_time - start_time:.3f}秒')
                    self.screenshot()
                    return loc
            except Exception as e:
                error_info = f"元素：{selector}定位失败，错误信息：{e}"
                self.log.error(error_info)
                if itme < retry:
                    end_time1 = time.time()
                    wait_time = (itme + 1) * 1000
                    self.log.info(
                        f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}，耗时：{end_time1 - start_time1:.3f}秒")
                    self.wait_for_timeout(wait_time)
                    send_message(f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}")

                    # self.browser_浏览器操作(reload=True)
                else:
                    self.page.close()
                    send_message(error_info)
                    self.screenshot()
                    raise Exception(error_info)


    def get_by_placeholder(self, selector, exact=False, retry=5, iframe=None, iframe_to=None,nth=0,hover=True):
        """
        使用get_by_text定位方式
        :param exact:
        :param selector: 元素位置
        :param retry: 重试次数
        :param iframe: iframe
        :param iframe_to: 嵌套iframe
        :return:
        """
        for itme in range(retry + 1):
            start_time1 = time.time()
            try:
                if iframe is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).get_by_placeholder(selector, exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                elif iframe_to is not None:
                    start_time = time.time()
                    loc = self.page.frame_locator(iframe).frame_locator(iframe_to).get_by_placeholder(selector,
                                                                                                exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()
                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,iframe为：{iframe},耗时：{end_time - start_time:.3f}秒')
                    return loc
                else:
                    start_time = time.time()
                    loc = self.page.get_by_placeholder(selector, exact=exact).nth(nth)
                    loc.wait_for(state="visible", timeout=10000)
                    loc.scroll_into_view_if_needed()
                    if hover:
                        loc.hover()

                    loc.evaluate(
                        "el => { el.style.backgroundColor = 'rgba(0, 0, 0, 0)'; el.style.border = '2.5px solid red'; }")
                    end_time = time.time()
                    self.log.info(f'元素：{selector}定位成功,耗时：{end_time - start_time:.3f}秒')
                    self.screenshot()
                    return loc
            except Exception as e:
                error_info = f"元素：{selector}定位失败，错误信息：{e}"
                self.log.error(error_info)
                if itme < retry:
                    end_time1 = time.time()
                    wait_time = (itme + 1) * 1000
                    self.log.info(
                        f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}，耗时：{end_time1 - start_time1:.3f}秒")
                    self.wait_for_timeout(wait_time)
                    send_message(f"元素：{selector}正在重新定位，当前重试次数：{itme + 1}/{retry}")

                    # self.browser_浏览器操作(reload=True)
                else:
                    self.page.close()
                    send_message(error_info)
                    self.screenshot()
                    raise Exception(error_info)
    #  ===================================locator==============================

    def click_locator(self, selector, num=0, force=True, iframe=None, iframe_to=None):
        """
        locator点击元素
        :param force:
        :param num:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'点击元素{selector}'):
                    if num >= 1:
                        with allure.step(f"点击:{selector}"):
                            if iframe is not None:

                                return self.locator(f"({selector})[{num}]", iframe=iframe).click(), self.log.info(
                                    f'元素:{selector} 点击成功，iframe:{iframe}')
                            elif iframe_to is not None:
                                self.hover_locator(selector)
                                return self.locator(selector=f"({selector})[{num}]", iframe=iframe,
                                                    iframe_to=iframe_to).click(), self.log.info(
                                    f'元素:{selector} 点击成功，iframe:{iframe}')
                            else:

                                return self.locator(selector=f"({selector})[{num}]").click(), self.log.info(
                                    f'元素: {selector} 点击成功')
                    else:
                        with allure.step(f"点击:{selector}"):
                            if iframe is not None:
                                return self.locator(selector, iframe=iframe).click(), self.log.info(
                                    f'元素:{selector} 点击成功，iframe:{iframe}')
                            elif iframe_to is not None:
                                return self.locator(selector=selector, iframe=iframe,
                                                    iframe_to=iframe_to).click(), self.log.info(
                                    f'元素:{selector} 点击成功，iframe:{iframe}')
                            else:
                                return self.locator(selector=selector).click(force=force), self.log.info(
                                    f'元素: {selector} 点击成功')
            except Exception as e:
                error_info = f'元素：{selector}点击失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f"元素{selector}正在重新点击，当前重试次数{i + 1}")
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def input_text_locator(self, selector, text, num=0, iframe=None, iframe_to=None):
        """
        locator输入文本
        :param num:
        :param selector:
        :param text:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                if num >= 1:
                    with allure.step(f"元素：{selector}输入:{text}"):
                        if iframe is not None:

                            ele = self.locator(f"({selector})[{num}]", iframe=iframe)
                            ele.clear(force=True)
                            ele.clear(force=True)
                            return ele.type(text, no_wait_after=True, delay=40), self.log.info(
                                f'内容:{text} 输入成功，iframe: {iframe}')

                        elif iframe_to is not None:

                            ele = self.locator(selector=f"({selector})[{num}]", iframe=iframe, iframe_to=iframe_to)
                            ele.clear(force=True)
                            ele.clear(force=True)

                            return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                                f'内容:{text} 输入成功，iframe:{iframe}，嵌套iframe：{iframe_to}')
                        else:

                            ele = self.locator(selector=f"({selector})[{num}]")
                            ele.clear(force=True)
                            ele.clear(force=True)
                            return ele.type(text, no_wait_after=True, delay=35), self.log.info(f'内容:{text} 输入成功')
                else:
                    with allure.step(f"元素：{selector}输入:{text}"):
                        if iframe is not None:

                            ele = self.locator(selector, iframe=iframe)
                            ele.clear(force=True)
                            ele.clear(force=True)
                            return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                                f'内容:{text} 输入成功，iframe: {iframe}')
                        elif iframe_to is not None:

                            ele = self.locator(selector=selector, iframe=iframe, iframe_to=iframe_to)
                            ele.clear(force=True)
                            ele.clear(force=True)
                            return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                                f'内容:{text} 输入成功，iframe:{iframe}，嵌套iframe：{iframe_to}')
                        else:
                            start_time = time.time()
                            ele = self.locator(selector)
                            ele.clear(force=True)
                            ele.clear(force=True)
                            ele.type(text, no_wait_after=True, delay=35)
                            end_time = time.time()
                            return ele, self.log.info(f'内容:{text} 输入成功,耗时：{end_time - start_time:.3f}秒')
            except Exception as e:
                error_info = f'内容:{text} 输入失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'内容：{text} 输入失败，正在重新输入，重试次数：{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def hover_locator(self, selector, num=1, iframe=None, iframe_to=None):
        """
        locator悬浮元素
        :param num:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f"悬浮到:{selector}"):
                    if iframe is not None:

                        ele = self.locator(f"({selector})[{num}]", iframe=iframe,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe}')
                    elif iframe_to is not None:

                        ele = self.locator(f"({selector})[{num}]", iframe=iframe, iframe_to=iframe_to,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe},嵌套iframe：{iframe_to}')
                    else:

                        ele = self.locator(f"({selector})[{num}]")
                        return ele.hover(timeout=100, force=True,hover=False), self.log.info(f'元素悬浮:{selector} 成功')
            except Exception as e:
                error_info = f'元素悬浮:{selector} 失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'元素{selector} 悬浮失败,正在重新悬浮，重试次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def file_locator(self, selector, files, iframe=None, iframe_to=None):
        """
        locator上传文件
        :param num:
        :param selector:
        :param files:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f"上传文件{files}"):
                    self.page.wait_for_timeout(150)
                    if iframe is not None:

                        return self.locator(selector, iframe=iframe).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    elif iframe_to is not None:

                        return self.locator(selector=selector, iframe=iframe,
                                            iframe_to=iframe_to).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    else:

                        return self.locator(selector).set_input_files(files=files), self.log.info(
                            f'上传：{files}  成功')
            except Exception as e:
                error_info = f'上传：{files}  失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'文件{files}上传失败，正在重新上传，重试次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def to_be_visible(self, selector, num=0, iframe=None, iframe_to=None,methon="loc"):
        """
        断言元素可见
        :param methon:
        :param num:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        try:
            with allure.step(f"断言元素{selector}可见"):
                if methon == 'loc':
                    if iframe is not None:
                        return expect(
                            self.locator(selector=selector, iframe=iframe,num=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.locator(selector=selector, iframe=iframe,
                                         iframe_to=iframe_to,num=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.locator(selector=selector,num=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                elif methon == 'text':
                    if iframe is not None:
                        return expect(
                            self.get_by_text(selector=selector, iframe=iframe,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_text(selector=selector, iframe=iframe,
                                         iframe_to=iframe_to,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_text(selector=selector,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                elif methon == 'role':
                    if iframe is not None:
                        return expect(
                            self.get_by_role(role_name=selector, iframe=iframe,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_role(role_name=selector, iframe=iframe,
                                         iframe_to=iframe_to,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_role(role_name=selector,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                elif methon == 'label':
                    if iframe is not None:
                        return expect(
                            self.get_by_label(selector=selector, iframe=iframe,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_label(selector=selector, iframe=iframe,
                                         iframe_to=iframe_to,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_label(selector=selector,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                elif methon == 'title':
                    if iframe is not None:
                        return expect(
                            self.get_by_title(selector=selector, iframe=iframe,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_title(selector=selector, iframe=iframe,
                                         iframe_to=iframe_to,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_title(selector=selector,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                elif methon == 'placeholder':
                    if iframe is not None:
                        return expect(
                            self.get_by_placeholder(selector=selector, iframe=iframe,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_placeholder(selector=selector, iframe=iframe,
                                         iframe_to=iframe_to,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_placeholder(selector=selector,nth=num)).to_be_visible(), self.log.info(
                            f'断言元素可见：{selector}，成功')

        except Exception as e:
            error_info = f'断言元素可见：{selector}，失败，错误信息：{e}'
            self.log.error(error_info)
            send_message(error_info)
            self.screenshot()
            raise Exception(e)

    def to_be_hidden(self, selector, num=0, iframe=None, iframe_to=None,methon="loc"):

        """
        断言元素不可见
        :param num:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        try:
            with allure.step(f"断言元素{selector}不可见"):

                if methon == 'loc':
                    if iframe is not None:
                        return expect(
                            self.locator(selector=selector, iframe=iframe, num=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.locator(selector=selector, iframe=iframe,
                                         iframe_to=iframe_to, num=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.locator(selector=selector, num=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                elif methon == 'text':
                    if iframe is not None:
                        return expect(
                            self.get_by_text(selector=selector, iframe=iframe, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_text(selector=selector, iframe=iframe,
                                             iframe_to=iframe_to, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_text(selector=selector, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                elif methon == 'role':
                    if iframe is not None:
                        return expect(
                            self.get_by_role(role_name=selector, iframe=iframe,
                                             nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_role(role_name=selector, iframe=iframe,
                                             iframe_to=iframe_to, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_role(role_name=selector, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                elif methon == 'label':
                    if iframe is not None:
                        return expect(
                            self.get_by_label(selector=selector, iframe=iframe,
                                              nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_label(selector=selector, iframe=iframe,
                                              iframe_to=iframe_to, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_label(selector=selector, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                elif methon == 'title':
                    if iframe is not None:
                        return expect(
                            self.get_by_title(selector=selector, iframe=iframe,
                                              nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_title(selector=selector, iframe=iframe,
                                              iframe_to=iframe_to, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_title(selector=selector, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                elif methon == 'placeholder':
                    if iframe is not None:
                        return expect(
                            self.get_by_placeholder(selector=selector, iframe=iframe,
                                                    nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_placeholder(selector=selector, iframe=iframe,
                                                    iframe_to=iframe_to, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(
                            self.get_by_placeholder(selector=selector, nth=num)).to_be_hidden(), self.log.info(
                            f'断言元素不可见：{selector}，成功')
        except Exception as e:
            error_info = f'断言元素不可见：{selector}，失败，错误信息：{e}'
            self.log.error(error_info)
            send_message(error_info)
            self.screenshot()
            raise Exception(e)

    def to_be_focused(self, selector, num=0, iframe=None, iframe_to=None,methon="loc"):
        """
        断言元素已获取焦点
        :param selector:
        :param num:
        :param iframe:
        :param iframe_to:
        :return:
        """
        try:
            with allure.step(f'断言元素{selector}已获取焦点'):

                if methon == 'loc':
                    if iframe is not None:
                        return expect(
                            self.locator(selector=selector, iframe=iframe, num=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.locator(selector=selector, iframe=iframe,
                                         iframe_to=iframe_to, num=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.locator(selector=selector, num=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                elif methon == 'text':
                    if iframe is not None:
                        return expect(
                            self.get_by_text(selector=selector, iframe=iframe, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_text(selector=selector, iframe=iframe,
                                             iframe_to=iframe_to, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_text(selector=selector, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                elif methon == 'role':
                    if iframe is not None:
                        return expect(
                            self.get_by_role(role_name=selector, iframe=iframe,
                                             nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_role(role_name=selector, iframe=iframe,
                                             iframe_to=iframe_to, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_role(role_name=selector, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                elif methon == 'label':
                    if iframe is not None:
                        return expect(
                            self.get_by_label(selector=selector, iframe=iframe,
                                              nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_label(selector=selector, iframe=iframe,
                                              iframe_to=iframe_to, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_label(selector=selector, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                elif methon == 'title':
                    if iframe is not None:
                        return expect(
                            self.get_by_title(selector=selector, iframe=iframe,
                                              nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_title(selector=selector, iframe=iframe,
                                              iframe_to=iframe_to, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_title(selector=selector, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                elif methon == 'placeholder':
                    if iframe is not None:
                        return expect(
                            self.get_by_placeholder(selector=selector, iframe=iframe,
                                                    nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_placeholder(selector=selector, iframe=iframe,
                                                    iframe_to=iframe_to, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(
                            self.get_by_placeholder(selector=selector, nth=num)).to_be_focused(), self.log.info(
                            f'断言元素已获取焦点：{selector}，成功')
        except Exception as e:
            error_info = f'断言元素已获取焦点：{selector}，失败，错误信息：{e}'
            self.log.error(error_info)
            send_message(error_info)
            self.screenshot()
            raise Exception(e)

    def to_contain_text(self, selector, text, num=0, iframe=None, iframe_to=None,methon="loc"):
        """
        断言包含文本
        :param num:
        :param selector:
        :param text:
        :param iframe:
        :param iframe_to:
        :return:
        """
        try:
            with allure.step(f"断言元素{selector}包含文本{text}"):

                if methon == 'loc':
                    if iframe is not None:
                        return expect(
                            self.locator(selector=selector, iframe=iframe, num=num)).to_contain_text(
                            text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.locator(selector=selector, iframe=iframe,
                                         iframe_to=iframe_to, num=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.locator(selector=selector, num=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                elif methon == 'text':
                    if iframe is not None:
                        return expect(
                            self.get_by_text(selector=selector, iframe=iframe, nth=num)).to_contain_text(
                            text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_text(selector=selector, iframe=iframe,
                                             iframe_to=iframe_to, nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_text(selector=selector, nth=num)).to_contain_text(
                            text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                elif methon == 'role':
                    if iframe is not None:
                        return expect(
                            self.get_by_role(role_name=selector, iframe=iframe,
                                             nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_role(role_name=selector, iframe=iframe,
                                             iframe_to=iframe_to, nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_role(role_name=selector, nth=num)).to_contain_text(
                            text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                elif methon == 'label':
                    if iframe is not None:
                        return expect(
                            self.get_by_label(selector=selector, iframe=iframe,
                                              nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_label(selector=selector, iframe=iframe,
                                              iframe_to=iframe_to, nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_label(selector=selector, nth=num)).to_contain_text(
                            text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                elif methon == 'title':
                    if iframe is not None:
                        return expect(
                            self.get_by_title(selector=selector, iframe=iframe,
                                              nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_title(selector=selector, iframe=iframe,
                                              iframe_to=iframe_to, nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(self.get_by_title(selector=selector, nth=num)).to_contain_text(
                            text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                elif methon == 'placeholder':
                    if iframe is not None:
                        return expect(
                            self.get_by_placeholder(selector=selector, iframe=iframe,
                                                    nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    elif iframe_to is not None:
                        return expect(
                            self.get_by_placeholder(selector=selector, iframe=iframe,
                                                    iframe_to=iframe_to, nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
                    else:
                        self.wait_for_timeout(150)
                        return expect(
                            self.get_by_placeholder(selector=selector, nth=num)).to_contain_text(text), self.log.info(
                            f'断言元素包含文本：{selector}，成功')
        except Exception as e:
            error_info = f'断言包含文本：{selector}失败,错误信息：{e}'
            self.log.error(error_info)
            send_message(error_info)
            self.screenshot()
            raise Exception(e)

    def to_be_false(self, selector, num=0, iframe=None, iframe_to=None):
        """
        断言元素不可交互
        :param selector:
        :param num:
        :param iframe:
        :param iframe_to:
        :return:
        """
        try:
            with allure.step(f'断言元素{selector}不可交互'):

                if iframe is not None:
                    element = self.locator(selector=selector, iframe=iframe,num=num)
                elif iframe_to is not None:
                    element = self.locator(selector=selector, iframe=iframe, iframe_to=iframe_to,num=num)
                else:
                    element = self.locator(selector=selector,num=num)

                # 尝试点击元素，如果失败则说明元素不可交互
                element.click(force=False, timeout=1500)
                error_info = f'断言元素不可交互：{selector}  失败，元素可点击'
                self.log.error(error_info)
                send_message(error_info)
                self.screenshot()
                pytest.fail(f"断言元素不可交互{selector}  失败，元素可点击")
        except Exception as e:
            with allure.step(f'断言元素{selector}不可交互'):
                self.log.info(f'断言元素不可交互：{selector}，成功')
                return True

    def to_have_url(self,url):
        """
        断言页面url
        :param url:
        :return:
        """
        try:
            with allure.step('断言页面url'):
                expect(self.page).to_have_url(url)
                self.log.info(f'断言页面url:{url} 成功')
        except Exception as e:
            error_info = f'断言页面url:{url} 失败，错误信息：{e}'
            self.log.error(error_info)
            send_message(error_info)
            raise Exception(e)


    def to_have_title(self,title):
        """
        断言页面title
        :param url:
        :return:
        """
        try:
            with allure.step('断言页面title'):
                expect(self.page).to_have_title(title)
                self.log.info(f'断言页面title:{title} 成功')
        except Exception as e:
            error_info = f'断言页面title:{title} 失败，错误信息：{e}'
            self.log.error(error_info)
            send_message(error_info)
            raise Exception(e)


    def browser_浏览器操作(self, reload=False, forward=False, back=False):
        """浏览器操作，reload 刷新，forward 前进，back 后退"""
        try:
            if reload:
                with allure.step('页面刷新成功'):
                    self.wait_for_timeout(150)
                    self.page.reload()
                    self.log.info(f"页面刷新成功")
                    # self.screenshot()
            if back:
                with allure.step('页面后退成功'):
                    self.wait_for_timeout(150)
                    self.page.go_back()
                    self.log.info(f"页面后退成功")
            if forward:
                with allure.step('页面前进成功'):
                    self.wait_for_timeout(150)
                    self.page.go_forward()
                    self.log.info(f"页面前进成功")
        except Exception as e:
            error_info = f'浏览器操作失败，错误信息：{e}'
            send_message(error_info)
            self.log.error(error_info)
            self.screenshot()

    #  ===================================get_by_text==============================
    def click_get_by_text(self, selector: str, exact=False, force=True, iframe=None, iframe_to=None, timeout=10000,nth=0):
        """
        点击
        :param force:强制点击
        :param exact: 表示是否精准匹配，默认false
        :param selector:元素定位
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f"点击元素{selector}"):
                    if iframe is not None:

                        return self.get_by_text(selector, exact=exact, iframe=iframe,nth=nth).click(force=force,
                                                                                            timeout=timeout), self.log.info(
                            f'元素:{selector} 点击成功，iframe:{iframe}')
                    elif iframe_to is not None:

                        return self.get_by_text(selector=selector, exact=exact, iframe=iframe,
                                                iframe_to=iframe_to,nth=nth).click(force=force, timeout=timeout), self.log.info(
                            f'元素:{selector} 点击成功，iframe:{iframe}')
                    else:

                        return self.get_by_text(selector, exact=exact,nth=nth).click(force=force,
                                                                             timeout=timeout), self.log.info(
                            f'元素: {selector} 点击成功')
            except Exception as e:
                error_info = f'元素：{selector}点击失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f"元素{selector}点击失败，正在重新点击，当前次数 {i + 1}")
                else:
                    self.log.error(error_info)
                    send_message(error_info)
                    self.screenshot()

    def input_text_get_by_text(self, selector, text, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        输入
        :param exact:
        :param selector:
        :param text:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f"元素{selector}输入: {text}"):
                    if iframe is not None:

                        ele = self.get_by_text(selector, exact=exact, iframe=iframe,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe: {iframe}')
                    elif iframe_to is not None:
                        ele = self.get_by_text(selector=selector, exact=exact, iframe=iframe, iframe_to=iframe_to,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe:{iframe}，嵌套iframe：{iframe_to}')
                    else:
                        start_time = time.time()
                        ele = self.get_by_text(selector=selector, exact=exact,nth=nth)
                        ele.clear(force=True)
                        ele.type(text, no_wait_after=True, delay=35)
                        end_time = time.time()
                        return ele, self.log.info(f'内容:{text} 输入成功,耗时：{end_time - start_time:.3f}秒')
            except Exception as e:
                error_info = f'内容:{text} 输入失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'内容{text}输入失败：正在重新输入，当前次数 {i + 1}')
                else:
                    self.log.error(error_info)
                    send_message(error_info)
                    self.screenshot()

    def hover_get_by_text(self, selector, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        元素悬浮
        :param exact:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f"悬浮到:{selector}"):
                    if iframe is not None:

                        ele = self.get_by_text(selector, exact=exact, iframe=iframe,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe}')
                    elif iframe_to is not None:

                        ele = self.get_by_text(selector, exact=exact, iframe=iframe, iframe_to=iframe_to,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe},嵌套iframe：{iframe_to}')
                    else:
                        ele = self.get_by_text(selector, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe}')
            except Exception as e:
                error_info = f'元素悬浮:{selector} 失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'元素{selector}悬浮失败，正在重新悬浮，当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def file_get_by_text(self, selector, files, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        文件上传
        :param exact:
        :param selector:
        :param files:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f"上传：{files}"):
                    if iframe is not None:

                        return self.get_by_text(selector, exact=exact, iframe=iframe,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    elif iframe_to is not None:

                        self.page.wait_for_timeout(150)
                        return self.get_by_text(selector=selector, exact=exact, iframe=iframe,
                                                iframe_to=iframe_to,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    else:

                        self.page.wait_for_timeout(150)
                        return self.get_by_text(selector, exact=exact,nth=nth).set_input_files(files=files), self.log.info(
                            f'上传：{files}  成功')
            except Exception as e:
                error_info = f'上传：{files}  失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'文件{files}上传失败，正在重新上传，当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def switch_window(self):
        """
        切换到当前窗口
        :return:
        """
        try:
            with allure.step("切换到当前窗口"):
                context = self.page.context
                pages = context.pages
                if not self.page:
                    raise Exception("在上下文中找不到页面")
                latest_page = pages[-1]
                latest_page.bring_to_front()
                self.page.wait_for_timeout(150)
                self.log.info("切换新窗口成功")
        except Exception as e:
            error_info = f'切换窗口失败，错误信息:{str(e)}'
            send_message(error_info)
            self.log.error(error_info)
            self.screenshot()

    #  ===================================get_by_role==============================
    def click_get_by_role(self, role_name: object, exact=False, force=True, iframe=None,
                          iframe_to=None, timeout=10000,nth=0):
        """
        点击
        :param force:
        :param exact:
        :param role_name:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f"点击元素{role_name}"):
                    if iframe is not None:

                        return self.get_by_role(role_name=role_name, exact=exact, iframe=iframe,nth=nth).click(
                            force=force, timeout=timeout), self.log.info(
                            f'元素:{role_name} 点击成功，iframe:{iframe}')
                    elif iframe_to is not None:

                        return self.get_by_role(role_name=role_name, iframe=iframe, iframe_to=iframe_to,
                                                exact=exact,nth=nth).click(force=force, timeout=timeout), self.log.info(
                            f'元素:{role_name} 点击成功，iframe:{iframe}')
                    else:

                        return self.get_by_role(role_name=role_name, exact=exact,nth=nth).click(force=force,
                                                                                        timeout=timeout), self.log.info(
                            f'元素: {role_name} 点击成功')
            except Exception as e:
                error_info = f'元素：{role_name}点击失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'元素{role_name}点击失败，正在重新点击，当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def input_text_get_by_role(self, role_name, text, exact=False, iframe=None, iframe_to=None, timeout=10000,nth=0):
        """
        输入
        :param exact:
        :param role_name:
        :param text:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'元素{role_name}输入文本：{text}'):
                    if iframe is not None:

                        ele = self.get_by_role(role_name=role_name, iframe=iframe, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe: {iframe}')
                    elif iframe_to is not None:

                        ele = self.get_by_role(role_name=role_name, iframe=iframe, iframe_to=iframe_to, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe:{iframe}，嵌套iframe：{iframe_to}')
                    else:
                        start_time = time.time()
                        ele = self.get_by_role(role_name=role_name, exact=exact,nth=nth)
                        ele.clear(force=True)
                        ele.type(text, no_wait_after=True, delay=35)
                        end_time = time.time()
                        return ele, self.log.info(f'内容:{text} 输入成功,耗时：{end_time - start_time:.3f}秒')
            except Exception as e:
                error_info = f'内容:{text} 输入失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'内容:{text}输入失败，正在重新输入，当前次数:{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def hover_get_by_role(self, role_name, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        元素悬浮
        :param exact:
        :param role_name:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'悬浮到：{role_name}'):
                    if iframe is not None:

                        ele = self.get_by_role(role_name=role_name, iframe=iframe, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{role_name} 成功，iframe: {iframe}')
                    elif iframe_to is not None:

                        ele = self.get_by_role(role_name=role_name, iframe=iframe, iframe_to=iframe_to, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{role_name} 成功，iframe: {iframe},嵌套iframe：{iframe_to}')
                    else:
                        ele = self.get_by_role(role_name=role_name, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(f'元素悬浮:{role_name} 成功')
            except Exception as e:
                error_info = f'元素悬浮:{role_name} 失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f"元素{role_name}悬浮失败，正在重新悬浮，当前次数 {i + 1}")
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def file_get_by_role(self, role_name, files, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        文件上传
        :param exact:
        :param role_name:
        :param files:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'上传：{files}'):
                    if iframe is not None:
                        return self.get_by_role(role_name=role_name, iframe=iframe, exact=exact,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    elif iframe_to is not None:
                        return self.get_by_role(role_name=role_name, iframe=iframe, iframe_to=iframe_to,
                                                exact=exact,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    else:

                        return self.get_by_role(role_name=role_name, exact=exact,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
            except Exception as e:
                error_info = f'上传：{files}  失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'上传{files}失败，正在重新上传，当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    #  ===================================get_by_label==============================
    def click_get_by_label(self, selector: str, exact=False, force=True, iframe=None, iframe_to=None, timeout=10000,nth=0):
        """
        点击
        :param force:
        :param exact:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'点击元素{selector}'):
                    if iframe is not None:
                        return self.get_by_label(selector, iframe=iframe, exact=exact,nth=nth).click(
                            force=force, timeout=timeout), self.log.info(
                            f'元素:{selector} 点击成功，iframe:{iframe}')
                    elif iframe_to is not None:

                        return self.get_by_label(selector=selector, iframe=iframe, iframe_to=iframe_to,
                                                 exact=exact,nth=nth).click(force=force, timeout=timeout), self.log.info(
                            f'元素:{selector} 点击成功，iframe:{iframe}')
                    else:

                        return self.get_by_label(selector, exact=exact,nth=nth).click(force=force,
                                                                              timeout=timeout), self.log.info(
                            f'元素: {selector} 点击成功')
            except Exception as e:
                error_info = f'元素：{selector}点击失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'元素{selector}点击失败，正在重新点击,当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def input_text_get_by_label(self, selector, text, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        输入
        :param exact:
        :param selector:
        :param text:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f"元素{selector} 输入文本：{text}"):
                    if iframe is not None:
                        ele = self.get_by_label(selector, iframe=iframe, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe: {iframe}')
                    elif iframe_to is not None:
                        ele = self.get_by_label(selector=selector, iframe=iframe, iframe_to=iframe_to, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe:{iframe}，嵌套iframe：{iframe_to}')
                    else:
                        ele = self.get_by_label(selector=selector, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(f'内容:{text} 输入成功')
            except Exception as e:
                error_info = f'内容:{text} 输入失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'内容{text}输入失败,正在重新输入，当前次数{i + 1}')
                send_message(error_info)
                self.log.error(error_info)
                self.screenshot()

    def hover_get_by_label(self, selector, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        元素悬浮
        :param exact:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'悬浮到：{selector}'):
                    if iframe is not None:
                        ele = self.get_by_label(selector, iframe=iframe, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe}')
                    elif iframe_to is not None:

                        ele = self.get_by_label(selector, iframe=iframe, iframe_to=iframe_to, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe},嵌套iframe：{iframe_to}')
                    else:
                        ele = self.get_by_label(selector, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe}')
            except Exception as e:
                error_info = f'元素悬浮:{selector} 失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f"元素{selector}悬浮失败，正在重新悬浮，当前次数 {i + 1}")
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def file_get_by_label(self, selector, files, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        文件上传
        :param exact:
        :param selector:
        :param files:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'上传:{files}'):
                    if iframe is not None:
                        return self.get_by_label(selector, iframe=iframe, exact=exact,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    elif iframe_to is not None:
                        return self.get_by_label(selector=selector, iframe=iframe, iframe_to=iframe_to,
                                                 exact=exact,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    else:
                        return self.get_by_label(selector, exact=exact,nth=nth).set_input_files(files=files), self.log.info(
                            f'上传：{files}  成功')
            except Exception as e:
                error_info = f'上传：{files}  失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'上传{files}失败，正在重新上传，当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    #  ===================================get_by_title==============================
    def click_get_by_title(self, selector: str, exact=False, force=True, iframe=None, iframe_to=None, timeout=10000,nth=0):
        """
        点击
        :param force:
        :param exact:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f' 点击元素{selector}'):
                    if iframe is not None:
                        return self.get_by_title(selector=selector, exact=exact, iframe=iframe,nth=nth).click(
                            force=force, timeout=timeout), self.log.info(
                            f'元素:{selector} 点击成功，iframe:{iframe}')
                    elif iframe_to is not None:

                        return self.get_by_title(selector=selector, exact=exact, iframe=iframe,
                                                 iframe_to=iframe_to,nth=nth).click(force=force,
                                                                            timeout=timeout), self.log.info(
                            f'元素:{selector} 点击成功，iframe:{iframe}')
                    else:

                        return self.get_by_title(selector=selector, exact=exact,nth=nth).click(force=force,
                                                                                       timeout=timeout), self.log.info(
                            f'元素: {selector} 点击成功')
            except Exception as e:
                error_info = f'元素：{selector}点击失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'元素{selector}点击失败，正在重新点击,当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def input_text_get_by_title(self, selector, text, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        输入
        :param exact:
        :param selector:
        :param text:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'元素{selector} 输入文本：{text}'):
                    if iframe is not None:

                        ele = self.get_by_title(selector, iframe=iframe, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe: {iframe}')
                    elif iframe_to is not None:

                        ele = self.get_by_title(selector=selector, iframe=iframe, iframe_to=iframe_to, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe:{iframe}，嵌套iframe：{iframe_to}')
                    else:

                        ele = self.get_by_title(selector=selector, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(f'内容:{text} 输入成功')
            except Exception as e:
                error_info = f'内容:{text} 输入失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'内容{text}输入失败,正在重新输入，当前次数{i + 1}')
                send_message(error_info)
                self.log.error(error_info)
                self.screenshot()

    def hover_get_by_title(self, selector, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        元素悬浮
        :param exact:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'悬浮到：{selector}'):
                    if iframe is not None:
                        ele = self.get_by_title(selector, iframe=iframe, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe}')
                    elif iframe_to is not None:
                        ele = self.get_by_title(selector, iframe=iframe, iframe_to=iframe_to, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe},嵌套iframe：{iframe_to}')
                    else:
                        ele = self.get_by_title(selector, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe}'), self.page.wait_for_timeout(150)
            except Exception as e:
                error_info = f'元素悬浮:{selector} 失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f"元素{selector}悬浮失败，正在重新悬浮，当前次数 {i + 1}")
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def file_get_by_title(self, selector, files, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        文件上传
        :param exact:
        :param selector:
        :param files:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'上传：{files}'):
                    if iframe is not None:
                        return self.get_by_title(selector, iframe=iframe, exact=exact,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    elif iframe_to is not None:
                        return self.get_by_title(selector=selector, iframe=iframe, iframe_to=iframe_to,
                                                 exact=exact,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    else:
                        return self.get_by_title(selector, exact=exact,nth=nth).set_input_files(files=files), self.log.info(
                            f'上传：{files}  成功')
            except Exception as e:
                error_info = f'上传：{files}  失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'上传{files}失败，正在重新上传，当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()


    #  ===================================get_by_title==============================
    def click_get_by_placeholder(self, selector: str, exact=False, force=True, iframe=None, iframe_to=None, timeout=10000,nth=0):
        """
        点击
        :param force:
        :param exact:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f' 点击元素{selector}'):
                    if iframe is not None:
                        return self.get_by_placeholder(selector=selector, exact=exact, iframe=iframe,nth=nth).click(
                            force=force, timeout=timeout), self.log.info(
                            f'元素:{selector} 点击成功，iframe:{iframe}')
                    elif iframe_to is not None:

                        return self.get_by_placeholder(selector=selector, exact=exact, iframe=iframe,
                                                 iframe_to=iframe_to,nth=nth).click(force=force,
                                                                            timeout=timeout), self.log.info(
                            f'元素:{selector} 点击成功，iframe:{iframe}')
                    else:

                        return self.get_by_placeholder(selector=selector, exact=exact,nth=nth).click(force=force,
                                                                                       timeout=timeout), self.log.info(
                            f'元素: {selector} 点击成功')
            except Exception as e:
                error_info = f'元素：{selector}点击失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'元素{selector}点击失败，正在重新点击,当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def input_text_get_by_placeholder(self, selector, text, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        输入
        :param exact:
        :param selector:
        :param text:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'元素{selector} 输入文本：{text}'):
                    if iframe is not None:

                        ele = self.get_by_placeholder(selector, iframe=iframe, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe: {iframe}')
                    elif iframe_to is not None:

                        ele = self.get_by_placeholder(selector=selector, iframe=iframe, iframe_to=iframe_to, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(
                            f'内容:{text} 输入成功，iframe:{iframe}，嵌套iframe：{iframe_to}')
                    else:

                        ele = self.get_by_placeholder(selector=selector, exact=exact,nth=nth)

                        ele.clear(force=True)
                        return ele.type(text, no_wait_after=True, delay=35), self.log.info(f'内容:{text} 输入成功')
            except Exception as e:
                error_info = f'内容:{text} 输入失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'内容{text}输入失败,正在重新输入，当前次数{i + 1}')
                send_message(error_info)
                self.log.error(error_info)
                self.screenshot()

    def hover_get_by_placeholder(self, selector, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        元素悬浮
        :param exact:
        :param selector:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'悬浮到：{selector}'):
                    if iframe is not None:
                        ele = self.get_by_placeholder(selector, iframe=iframe, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe}')
                    elif iframe_to is not None:
                        ele = self.get_by_placeholder(selector, iframe=iframe, iframe_to=iframe_to, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe},嵌套iframe：{iframe_to}')
                    else:
                        ele = self.get_by_placeholder(selector, exact=exact,nth=nth,hover=False)
                        return ele.hover(timeout=350, force=True), self.log.info(
                            f'元素悬浮:{selector} 成功，iframe: {iframe}'), self.page.wait_for_timeout(150)
            except Exception as e:
                error_info = f'元素悬浮:{selector} 失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f"元素{selector}悬浮失败，正在重新悬浮，当前次数 {i + 1}")
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()

    def file_get_by_placeholder(self, selector, files, exact=False, iframe=None, iframe_to=None,nth=0):
        """
        文件上传
        :param exact:
        :param selector:
        :param files:
        :param iframe:
        :param iframe_to:
        :return:
        """
        for i in range(self.retry + 1):
            try:
                with allure.step(f'上传：{files}'):
                    if iframe is not None:
                        return self.get_by_placeholder(selector, iframe=iframe, exact=exact,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    elif iframe_to is not None:
                        return self.get_by_placeholder(selector=selector, iframe=iframe, iframe_to=iframe_to,
                                                 exact=exact,nth=nth).set_input_files(
                            files=files), self.log.info(
                            f'上传：{files}  成功')
                    else:
                        return self.get_by_placeholder(selector, exact=exact,nth=nth).set_input_files(files=files), self.log.info(
                            f'上传：{files}  成功')
            except Exception as e:
                error_info = f'上传：{files}  失败，错误信息：{e}'
                if i < self.retry:
                    self.log.info(f'上传{files}失败，正在重新上传，当前次数{i + 1}')
                else:
                    send_message(error_info)
                    self.log.error(error_info)
                    self.screenshot()


    def screenshot(self):
        with allure.step(f"🪞截图时间:{time.strftime('%H:%M:%S', time.localtime(time.time()))}🪞"):
            allure.attach(self.page.screenshot(animations="disabled", timeout=5000), '🪞测试截图🪞',
                          allure.attachment_type.PNG)

    # @allure.step("截图")
    # def screenshot(self):
    #     # 获取当前页面的URL
    #     current_url = self.page.url
    #
    #     # 检查URL是否以 http://localhost:5173/design?pid= 开头
    #     if current_url.startswith("http://localhost:5173/design?pid="):
    #         # 使用当前URL作为文件名的基础，添加时间戳以避免重复
    #         current_time = time.strftime('%Y%m%d_%H%M%S', time.localtime(time.time()))
    #         # 替换URL中的非法字符
    #         sanitized_url = current_url.replace(':', '').replace('/', '_').replace('?', '_')
    #         filename = f"{sanitized_url}_{current_time}.png"
    #         screenshots_dir = "screenshots"
    #
    #         # 确保 screenshots 文件夹存在
    #         if not os.path.exists(screenshots_dir):
    #             os.makedirs(screenshots_dir)
    #
    #         # 截图并保存到 screenshots 文件夹
    #         screenshot_data = self.page.screenshot(animations="disabled", timeout=5000)
    #         with open(os.path.join(screenshots_dir, filename), "wb") as file:
    #             file.write(screenshot_data)
    #
    #         with allure.step(f"截图时间: {current_time}"):
    #             # 将截图也附加到 Allure 报告中
    #             allure.attach(screenshot_data, f'{current_url}', allure.attachment_type.PNG)
    #     else:
    #         print("URL 未以指定的前缀开头，屏幕截图未保存。")

    def expect_assert(self, locator):
        try:
            with allure.step(f'断言:{locator}'):
                self.log.info('断言成功')
                return expect(locator)
        except Exception as e:
            error_info = f'断言失败，错误信息：{e}'
            send_message(error_info)
            self.log.error(error_info)
            self.screenshot()

    def wait_for_timeout(self, timeout=None):
        self.log.info(f'等待:{timeout / 1000}秒')
        return self.page.wait_for_timeout(timeout=timeout)


    # def get_text(self, selector, num=0, iframe=None, iframe_to=None,methon="loc"):
    #     """
    #     提取文本
    #     :param num:
    #     :param selector:
    #     :param text:
    #     :param iframe:
    #     :param iframe_to:
    #     :return:
    #     """
    #     try:
    #         with allure.step(f"提取元素{selector}文本"):
    #
    #             if methon == 'loc':
    #                 if iframe is not None:
    #
    #                         text = self.locator(selector=selector, iframe=iframe, num=num).inner_text()
    #                         self.log.info(f'提取元素:{selector}文本：{text}，成功')
    #                         return text
    #                 elif iframe_to is not None:
    #
    #                         text=self.locator(selector=selector, iframe=iframe,iframe_to=iframe_to, num=num).inner_text()
    #                         self.log.info(f'提取元素:{selector}文本：{text}，成功')
    #                         return text
    #                 else:
    #                     text = self.locator(selector=selector, num=num).inner_text()
    #                     self.log.info(f'提取元素:{selector}文本：{text}，成功')
    #                     return text
    #             elif methon == 'text':
    #                 if iframe is not None:
    #                     text = self.get_by_text(selector=selector, iframe=iframe, nth=num).inner_text()
    #                     self.log.info(f'提取元素:{selector}文本：{text}，成功')
    #                     return text
    #                 elif iframe_to is not None:
    #                     text = self.get_by_text(selector=selector, iframe=iframe,iframe_to=iframe_to,nth=num).inner_text()
    #                     self.log.info(f'提取元素:{selector}文本：{text}，成功')
    #                     return text
    #                 else:
    #                     text = self.get_by_text(selector=selector, nth=num).inner_text()
    #                     self.log.info(f'提取元素:{selector}文本：{text}，成功')
    #                     return text
    #             elif methon == 'role':
    #                 if iframe is not None:
    #                     text = self.get_by_role(role_name=selector, iframe=iframe, nth=num).inner_text()
    #                     self.log.info(f'提取元素:{selector}文本：{text}，成功')
    #                     return text
    #                 elif iframe_to is not None:
    #                     text = self.get_by_role(role_name=selector, iframe=iframe, iframe_to=iframe_to,nth=num).inner_text()
    #                     self.log.info(f'提取元素:{selector}文本：{text}，成功')
    #                     return text
    #                 else:
    #                     self.wait_for_timeout(150)
    #                     return expect(self.get_by_role(role_name=selector, nth=num)).to_contain_text(
    #                         text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #             elif methon == 'label':
    #                 if iframe is not None:
    #                     return expect(
    #                         self.get_by_label(selector=selector, iframe=iframe,
    #                                           nth=num)).to_contain_text(text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #                 elif iframe_to is not None:
    #                     return expect(
    #                         self.get_by_label(selector=selector, iframe=iframe,
    #                                           iframe_to=iframe_to, nth=num)).to_contain_text(text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #                 else:
    #                     self.wait_for_timeout(150)
    #                     return expect(self.get_by_label(selector=selector, nth=num)).to_contain_text(
    #                         text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #             elif methon == 'title':
    #                 if iframe is not None:
    #                     return expect(
    #                         self.get_by_title(selector=selector, iframe=iframe,
    #                                           nth=num)).to_contain_text(text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #                 elif iframe_to is not None:
    #                     return expect(
    #                         self.get_by_title(selector=selector, iframe=iframe,
    #                                           iframe_to=iframe_to, nth=num)).to_contain_text(text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #                 else:
    #                     self.wait_for_timeout(150)
    #                     return expect(self.get_by_title(selector=selector, nth=num)).to_contain_text(
    #                         text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #             elif methon == 'placeholder':
    #                 if iframe is not None:
    #                     return expect(
    #                         self.get_by_placeholder(selector=selector, iframe=iframe,
    #                                                 nth=num)).to_contain_text(text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #                 elif iframe_to is not None:
    #                     return expect(
    #                         self.get_by_placeholder(selector=selector, iframe=iframe,
    #                                                 iframe_to=iframe_to, nth=num)).to_contain_text(text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #                 else:
    #                     self.wait_for_timeout(150)
    #                     return expect(
    #                         self.get_by_placeholder(selector=selector, nth=num)).to_contain_text(text), self.log.info(
    #                         f'断言元素包含文本：{selector}，成功')
    #     except Exception as e:
    #         error_info = f'断言包含文本：{selector}失败,错误信息：{e}'
    #         self.log.error(error_info)
    #         send_message(error_info)
    #         self.screenshot()
    #         raise Exception(e)






